//////////////////////////////////////////////////////////////////////
//
//  expandscalars_cimp.cpp
//
//  The C-mex implementation to expand scalars
//
//  Created by Dahua Lin, on Dec 19, 2007
//
//////////////////////////////////////////////////////////////////////


#include "mex.h"

int count_nums(int n0, const int* nums)
{
	int c = 0;
	for (int i = 0; i < n0; ++i)
	{
		c += nums[i];
	}
	
	return c;
}


void expand_scalars(int n0, const int *v0, const int* nums, int *v)
{	
	int i = 0;
	for (int i = 0; i < n0; ++i)
	{
		int cn = nums[i];		
		
		if (cn > 0)
		{
			int cv = v0[i];
			for (int j = 0; j < cn; ++j)
				*v++ = cv;
		}
	}
}

/*
 * main entry:
 *
 * Input
 *  - v0:   source scalars (int32)
 *  - nums: the number of expansions (int32)
 *
 * Output
 *  - v:    expanded vector of scalars (row vector int32)
 *
 * For efficiency, no argument checking inside.
 */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	const mxArray* mxV0 = prhs[0];
	const mxArray* mxNums = prhs[1];
	
	int n0 = mxGetNumberOfElements(mxV0);
	const int* v0 = reinterpret_cast<const int*>(mxGetData(mxV0));
	const int* nums = reinterpret_cast<const int*>(mxGetData(mxNums));
	
	int c = count_nums(n0, nums);

	mxArray *mxV = mxCreateNumericMatrix(1, c, mxINT32_CLASS, mxREAL);

	expand_scalars(n0, v0, nums, reinterpret_cast<int*>(mxGetData(mxV)));

	plhs[0] = mxV;	
}
